#include <iostream>
#include <cstring>
#include <cerrno>
#include <fcntl.h>
#include <unistd.h>

// int fcntl(int fd, int cmd, ... /* arg */ );
bool SetNonBlock(int fd)
{
    // F_GETFL: Get the file access mode and the file status flags; arg is ignored.
    int fl = fcntl(fd, F_GETFL); // 在底层获取当前fd对应的文件读写标志位
    if (fl < 0)
    {
        return false;
    }

    int ret = fcntl(fd, F_SETFL, fl | O_NONBLOCK); // 设置为非阻塞状态(不管是读还是写)

    return -1 != ret;
}

int main()
{
    SetNonBlock(0);

    // 0:标准输入 1:标准输出 2:标准错误

    char buffer[1024];
    memset(buffer, 0, sizeof(buffer));

    while (true)
    {
        errno = 0;

        int n = read(0, buffer, sizeof(buffer) - 1);

        if (n > 0)
        {
            std::cout << "Echo # " << buffer << std::endl;
        }
        else
        {
            std::cout << "read \"error\" "
                      << " errno: " << errno << " errstring: " << strerror(errno) << std::endl;

            // 如果失败的errno值是11，就代表其实没错，只不过是底层数据没就绪
            if (errno == EWOULDBLOCK || errno == EAGAIN)
            {
                std::cout << "当前0号fd数据没有就绪, 请下一次再来试试吧" << std::endl;
                continue;
            }
            else if (errno == EINTR)
            {
                std::cout << "当前0号fd数据没有就绪, 请下一次再来试试吧" << std::endl;
                continue;
            }
            else
            {
                // 进行差错处理
            }
        }
        sleep(1);
    }

    return 0;
}
